﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnisysMassiveImporter_v2.Entidades.Configuracion;
using UnisysMassiveImporter_v2.Entidades.Mensajes;
using System.Threading.Tasks;
using System.Collections;
using UnisysMassiveImporter_v2.Entidades.Documentos;

namespace UnisysMassiveImporter_v2.Negocio.Administrators
{
    public class TaskAdministrator
    {
        

        private bool Continue = true;
        private bool IsRunning;

        private InfoMessage message;

        public TaskAdministrator()
        {
            
            message = new InfoMessage();
        }

        private ArrayList sort(int tamano, ArrayList izquierda, ArrayList derecha)
        {
            int i = 0, j = 0;
            System.IO.FileInfo file1, file2;
            ArrayList sortedList = new ArrayList();
            for (int k = 0; k < tamano; k++)
            {


                if (i >= izquierda.Count)
                { sortedList.Add(derecha[j]); j++; continue; }
                else
                { file1 = new System.IO.FileInfo(((Document)izquierda[i]).filePath); }

                if (j >= derecha.Count)
                { sortedList.Add(izquierda[i]); i++; continue; }
                else
                { file2 = new System.IO.FileInfo(((Document)derecha[j]).filePath); }


                if ((file1.CreationTime) < (file2.CreationTime))
                { sortedList.Add(izquierda[i]); i++; }
                else
                { sortedList.Add(derecha[j]); j++; }

            }
            return sortedList;
        }

        private ArrayList sortList(ArrayList list, ref Configuration appConfig, ref Thread_Config ThreadConfiguration)
        {
            message.sendMessage("Ordenando el data previewList", InfoMessage.Information_Message, 539, ThreadConfiguration.Name, ref appConfig);
            if (list.Count <= 1)
                return list;
            else
            {
                int mitad = (list.Count) / 2;
                ArrayList der;
                if (((list.Count) % 2) == 0)
                    der = list.GetRange(mitad, mitad);
                else
                    der = list.GetRange(mitad, mitad + 1);

                ArrayList izq = list.GetRange(0, mitad);


                return sort(list.Count, sortList(izq, ref appConfig, ref ThreadConfiguration), sortList(der, ref appConfig, ref ThreadConfiguration));
            }
        }



        public void Start(Configuration appConfig, Thread_Config ThreadConfiguration)
        {
            message.sendMessage("Iniciando Tarea...", InfoMessage.Information_Message, 538, ThreadConfiguration.Name, ref appConfig);
            Task t = Task.Factory.StartNew(() => Run(ref appConfig, ref ThreadConfiguration));
            message.sendMessage("Tarea Generada", InfoMessage.Success_Message, 265, ThreadConfiguration.Name, ref appConfig);
        }

        private void Run(ref Configuration appConfig, ref Thread_Config ThreadConfiguration)
        {
            do
            {
                IsRunning = true;
                message.sendMessage("Reanudando Ciclo...", InfoMessage.Information_Message, 544, ThreadConfiguration.Name, ref appConfig);
                Archivos.Manipulacion_Archivos manipulacionArchivos = new Archivos.Manipulacion_Archivos();
                //obtener data....LISTO....
                //bloquear data...por desicion de equipo paso omitido...
                //leer data...LISTO...
                //buscar imagenes...LISTO                
                //procesar archivos(indexar)...LISTO
                //subir imagenes...LISTO
                //generar historico...    LISTO
                if ((ThreadConfiguration.DirectoryOrganization <= 3) && (ThreadConfiguration.DirectoryOrganization >= 1))
                {
                    ArrayList previewList = null;
                    try
                    {
                        message.sendMessage("Creando previewList de data", InfoMessage.Information_Message, 545, ThreadConfiguration.Name, ref appConfig);
                        previewList = manipulacionArchivos.getDataPreview(ref appConfig, ref ThreadConfiguration);
                        message.sendMessage("PreviewList de data creado", InfoMessage.Success_Message, 267, ThreadConfiguration.Name, ref appConfig);
                    }
                    catch (Exception e)
                    {
                        FileMessage fMessage=new FileMessage("El previewList tuvo problemas de creacion. El thread quedo en estado wait, se intentara reprocesar de nuevo.", e,"PreviewList", 103,  ThreadConfiguration.Name);
                        fMessage.sendMessage(ref appConfig);
                        IsRunning = false;
                        System.Threading.Thread.Sleep(((ThreadConfiguration.Delay * 60) * 1000));
                        continue;
                    }
                    MailMessage mail = new MailMessage();
                    if (previewList != null)
                    {
                        
                        message.sendMessage("Se encontraron " + previewList.Count + " archivos", InfoMessage.Information_Message, 546, ThreadConfiguration.Name,ref appConfig);
                        //ordenar lista el ultimo archivo creado
                        previewList = sortList(previewList,ref appConfig,ref ThreadConfiguration);
                        message.sendMessage("Data PreviewList ha sido ordenado", InfoMessage.Success_Message, 268, ThreadConfiguration.Name, ref appConfig);
                        manipulacionArchivos.printList(previewList, ref appConfig, ref ThreadConfiguration);

                        try
                        {
                            mail = manipulacionArchivos.createDocuments(previewList, ref appConfig, ref ThreadConfiguration);
                            message.sendMessage("PreviewList ha subido procesado con exito", InfoMessage.Success_Message, 278, ThreadConfiguration.Name, ref appConfig);  
                        }
                        catch(Exception e)
                        {
                            CriticalMessage cMessage=new CriticalMessage("Error inesperado de procesamiento. El thread quedo en estado wait, se intentara reprocesar de nuevo.",e,CriticalMessage.Configuration_Error,60,ThreadConfiguration.Name,false);
                            cMessage.sendMessage(ref appConfig);
                        }

                        
                        if (appConfig.historyGeneration)
                        {                            
                                for (int i = 0; i < previewList.Count; i++)
                                {
                                    Document file = (Document)previewList[i];
                                    manipulacionArchivos.historyDataGeneration(file,ref appConfig, ref ThreadConfiguration);
                                }                           
                        }
                        else//no generar historico, eliminando archivos
                        {
                            for (int i = 0; i < previewList.Count; i++)
                            {
                                Document file = (Document)previewList[i];
                                manipulacionArchivos.historyDataDelete(file,ref appConfig,ref ThreadConfiguration);
                            }
                        }
                        
                        

                        message.sendMessage("\n Total Archivos: " + mail.files + "\n Total Documentos Procesados Correctamente:" + mail.documentsOk + "\n Total Documentos Sin Procesar:" + mail.documentsNoOk, InfoMessage.Success_Message, 290, ThreadConfiguration.Name,ref appConfig);
                        mail.sendMessage( ThreadConfiguration.Name,ref appConfig);
                       
                        
                    }
                    else
                        message.sendMessage("No se encontraron archivos a procesar en la carpeta: " + ThreadConfiguration.DataPath, InfoMessage.Success_Message, 271, ThreadConfiguration.Name, ref appConfig);

                    
                }
                else
                {
                    CriticalMessage cMessage=new CriticalMessage("La organizacion de directorios en la configuracion es incorrecta",new Exception("Valor Actual del DirectoryOrganization: "+ThreadConfiguration.DirectoryOrganization+". Valor Invalido"),CriticalMessage.Configuration_Error,59,ThreadConfiguration.Name,false);
                    cMessage.sendMessage(ref appConfig);
                }

                //fin del proceso se va al wait
                IsRunning = false;
                message.sendMessage("Entrando en modo Wait.", InfoMessage.Information_Message, 107, ThreadConfiguration.Name, ref appConfig);
                System.Threading.Thread.Sleep(((ThreadConfiguration.Delay * 60) * 1000));
            }
            while (Continue);
        }
    }
}
